package time_windown

import (
	"sync"
	"time"
)

/* 滑动时间窗口，针对某一个实体的频率控制 */
type RateLimiterV1 struct {
	WindowsSize time.Duration     // 窗口大小
	maxCount    int               // 最大数量
	counts      map[time.Time]int // 记录存档
	mu          sync.RWMutex
}

// 判断是否超过频率, 没有超过频率-true
func (r *RateLimiterV1) Allow() bool {
	/* 通过时间推移，判断存档的记录情况，过期则覆盖，否则判断是否超频 */
	r.mu.Lock()
	defer r.mu.Unlock()

	// 获取当前时间状态与记录比较
	now := time.Now()

	for k := range r.counts {
		if k.Add(r.WindowsSize).Before(now) {
			// 过期数据无用
			delete(r.counts, k)
		}
	}

	// 超过限制
	if len(r.counts) >= r.maxCount {
		return false
	}

	r.counts[now]++

	return true
}

// 此版本实现，可以控制单个值(实体)在时间窗口内的出现频率

// 但是，针对map的遍历无疑是比较耗费时间的
// 而且，如果要统计多个值(实体)在窗口内的出现频率呢？应该怎么修改？
